package com.zhixun.mobile.modules.jiujiudevice.device.task;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.boxin.ims.modules.jiujiudevice.entity.JiuDevice;
import com.boxin.ims.modules.jiujiudevice.entity.JiuInk;
import com.boxin.ims.modules.jiujiudevice.entity.JiuSn;
import com.boxin.ims.modules.jiujiudevice.service.JiuInkService;
import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.utils.JedisUtils;
import com.zhixun.mobile.modules.jiujiudevice.device.model.DataModel;
import com.zhixun.mobile.modules.jiujiudevice.device.model.InkModel;
import com.zhixun.mobile.modules.jiujiudevice.device.threadpool.SmartThreadPool;
import com.zhixun.mobile.modules.jiujiudevice.device.util.BytesHexStrTranslate;
import com.zhixun.mobile.modules.jiujiudevice.device.util.DeviceCodeEnums;
import com.zhixun.mobile.modules.jiujiudevice.device.util.Hog;
import com.zhixun.mobile.modules.jiujiudevice.device.util.SocketUtils;

public class Task implements Runnable {

	// 与某个客户端的连接会话，需要通过它来给客户端发送数据
	private Socket socket;
	private JiuInkService jiuInkService;
	/**
	 * 用来存储各路线的所有重量值
	 */
	
	public static ConcurrentHashMap<String,List<InkModel>> allmap = new ConcurrentHashMap<String,List<InkModel>>();
	
	private static final String OPEN_DEVICE = "0";//开关设备
	private static final String OPEN_INK_DEVICE = "1";//加墨设备
 
	/**
	 * 构造函数
	 */

	public Task(Socket socket,JiuInkService jiuInkService) {
		this.socket = socket;
		this.jiuInkService = jiuInkService;
	}

	@Override
	public void run() {
		
		
		
		Hog.i("有新连接加入...\n" + "线程名->{}\n" + "线程池活动数量 = {}\n" + "线程池最大数量 = {}\n" + "线程池执行的任务次数 = {}\n",
				Thread.currentThread().getName(), SmartThreadPool.getSmartThreadPool().getActiveCount(),
				SmartThreadPool.getSmartThreadPool().getMaximumPoolSize(),
				SmartThreadPool.getSmartThreadPool().getTaskCount());

		try {
			handlerSocket();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 跟客户端Socket进行通信 此处在服务端主动断开与客户端的链接
	 * 
	 * @throws IOException
	 */
	/**
	 * @function: <p> </p>
	 */
	private void handlerSocket() {

		int BUFSIZE = 1024;
		int recvMsgSize;
		byte[] receiveBuf = new byte[BUFSIZE];
		// b,使用所返回的Socket实例的InputStream和OutputStream与客户端进行通信
		InputStream in = null;
		OutputStream out = null;
		try {
			in = socket.getInputStream();
			out = socket.getOutputStream();
			/* while ((recvMsgSize = in.read(receiveBuf)) != -1) { */
			recvMsgSize = in.read(receiveBuf);
			Hog.i("数据报长度={}", recvMsgSize);
			System.out.println("设备接收信息========》" + new String(receiveBuf, 0, recvMsgSize));

			if (recvMsgSize <= 0) {
				Hog.i("长度不足,直接返回");
				return;
			}
			
		  
		   Map<String, Object> map = SocketUtils.jsonToMap(new String(receiveBuf, 0, recvMsgSize));
		   	   //如果有sn，说明有数据传输
			   //处理单独开关逻辑
				String sn = (String) map.get("sn");
				//设备开关 0-close 1-open
				String sta1 = (String) map.get("sta1");
				//缓存所有的设备,排除断电的设备
				JedisUtils.setObject(JiuSn.DEVICE_EXSIT+"_"+sn, System.currentTimeMillis(), 0);
				//如果加墨开关有值，说明是加墨设备
				if(map.containsKey("sta2")){
					//加墨开关 0-close 1-open
					String sta2 = (String) map.get("sta2");
					//获取1-8路的数据
					String v1 = (String) map.get("v1");
					String v2 = (String) map.get("v2");
					String v3 = (String) map.get("v3");
					String v4 = (String) map.get("v4");
					String v5 = (String) map.get("v5");
					String v6 = (String) map.get("v6");
					String v7 = (String) map.get("v7");
					String v8 = (String) map.get("v8");
					
				 	Hog.e("加墨设备socket传入的sn = {},sta1 = {},sta2 = {},v1 = {},v2 = {},v3 = {},v4 = {},v5 = {},v6 = {},v7 = {},v8 = {}", sn, sta1, sta2, v1, v2, v3, v4, v5, v6, v7, v8);
				 	String key = sn;
					out.write(BytesHexStrTranslate.toBytes(DeviceCodeEnums.OPEN.getCode()));
					InkModel ink = new InkModel();
					ink.setSn(sn);
					ink.setSnStatus(sta1);
					ink.setInkStatus(sta2);
					//设置各路线的数据
					List<DataModel> dList  = Lists.newArrayList();
					
					//查询改设备有几路
					List<JiuInk> inkList = jiuInkService.findBySn(key);
					int route = 0;
					if(inkList != null){
						//如果设备配置了墨盒，按照设备的设置设置几路
						route = inkList.size();
					}else{
						//如果设备没有配置 ，默认的8路
						route = 8;
					}
				    //设置8路的数据
					for(int i=1;i<=route;i++){
						DataModel data = new DataModel();
						data.setId(i+"");
						data.setValue(Double.parseDouble((String) map.get("v"+i)));
						if(inkList != null){
							data.setFlag(inkList.get(i-1).getColor());
							data.setPrice(inkList.get(i-1).getPrice());
						}
						
						dList.add(data);
					}
					ink.setDatalist(dList);
					//缓存设备最新的墨盒数据
					JedisUtils.setObject(JiuDevice.DEVICE_CUR_DATA+"_"+sn, ink, 0);
					// 核心业务s
					if (JedisUtils.exists(JiuDevice.DEVICE_RUNTIME_KEY_PREFIX + sn)) {
						Hog.e("打开设备 sn = {}", sn);
						if(JedisUtils.exists(key)){				
							List<InkModel> l = (List<InkModel>) JedisUtils.getObject(key);
							l.add(ink);	
							JedisUtils.setObject(key, l, 0);
						}else{
							List<InkModel> l = new ArrayList<InkModel>();
							l.add(ink);	
							JedisUtils.setObject(key, l, 0);
						}		
					} else {
						Hog.e("删除设备 sn = {} , openId = {} time = {}", sn);
						Hog.e("关闭设备 sn = {}", sn);
						out.write(BytesHexStrTranslate.toBytes(DeviceCodeEnums.CLOSE.getCode()));
					}
					//存储设备是开关设备还是加墨设备
					JedisUtils.setObject(JiuDevice.DEVICE_TYPE+sn,OPEN_INK_DEVICE , 0);
				}else{
					// 处理单独的开关逻辑
					if (JedisUtils.exists(JiuDevice.DEVICE_RUNTIME_KEY_PREFIX + sn)) {
						Hog.e("打开设备 sn = {}", sn);
						Hog.e("开关设备socket传入的sn = {},sta1 = {}", sn, sta1);
						out.write(BytesHexStrTranslate.toBytes(DeviceCodeEnums.OPEN.getCode()));
					} else {
						Hog.e("删除设备 sn = {} , openId = {} time = {}", sn);
						Hog.e("关闭设备 sn = {}", sn);
						out.write(BytesHexStrTranslate.toBytes(DeviceCodeEnums.CLOSE.getCode()));
					}
					//存储设备是开关设备还是加墨设备
					JedisUtils.setObject(JiuDevice.DEVICE_TYPE + sn,OPEN_DEVICE , 0);
				}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeFunction(in, out, socket);
		}

	}

	/**
	 * 关闭流
	 * 
	 * @param in
	 * @param out
	 * @param socket
	 */
	void closeFunction(InputStream in, OutputStream out, Socket socket) {
		try {
			if (null != in) {
				in.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			if (null != out) {
				out.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			if (null != socket) {
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
